From a05c7f41031a0ab44c8bfea241e74c7daad6d880 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 16 Apr 2007 11:35:58 +0100 Subject: [PATCH] hvm: Fix a bug in the mmio emulation of SUB instruction. Signed-off-by: Dexuan Cui --- tools/ioemu/target-i386-dm/helper2.c | 18 ++++++++++++++++++ xen/arch/x86/hvm/platform.c | 5 ++++- xen/include/public/hvm/ioreq.h | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index 7beda011c6..513d925b73 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -408,6 +408,21 @@ void cpu_ioreq_add(CPUState *env, ioreq_t *req) req->data = tmp1; } +void cpu_ioreq_sub(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + + if (req->data_is_ptr != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { + tmp2 = tmp1 - (unsigned long) req->data; + write_physical(req->addr, req->size, &tmp2); + } + req->data = tmp1; +} + void cpu_ioreq_or(CPUState *env, ioreq_t *req) { unsigned long tmp1, tmp2; @@ -496,6 +511,9 @@ void __handle_ioreq(CPUState *env, ioreq_t *req) case IOREQ_TYPE_ADD: cpu_ioreq_add(env, req); break; + case IOREQ_TYPE_SUB: + cpu_ioreq_sub(env, req); + break; case IOREQ_TYPE_OR: cpu_ioreq_or(env, req); break; diff --git a/xen/arch/x86/hvm/platform.c b/xen/arch/x86/hvm/platform.c index 8bb3e3439b..caa2b377c9 100644 --- a/xen/arch/x86/hvm/platform.c +++ b/xen/arch/x86/hvm/platform.c @@ -1240,6 +1240,10 @@ void handle_mmio(unsigned long gpa) mmio_operands(IOREQ_TYPE_ADD, gpa, mmio_op, op_size); break; + case INSTR_SUB: + mmio_operands(IOREQ_TYPE_SUB, gpa, mmio_op, op_size); + break; + case INSTR_XOR: mmio_operands(IOREQ_TYPE_XOR, gpa, mmio_op, op_size); break; @@ -1261,7 +1265,6 @@ void handle_mmio(unsigned long gpa) case INSTR_CMP: /* Pass through */ case INSTR_TEST: - case INSTR_SUB: /* send the request and wait for the value */ send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, op_size, 0, IOREQ_READ, df, 0); break; diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 063810cc74..e9f6495e21 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -41,6 +41,7 @@ #define IOREQ_TYPE_ADD 6 #define IOREQ_TYPE_TIMEOFFSET 7 #define IOREQ_TYPE_INVALIDATE 8 /* mapcache */ +#define IOREQ_TYPE_SUB 9 /* * VMExit dispatcher should cooperate with instruction decoder to -- 2.30.2